package com.atguigu.gmall.threadpool;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author 卡尼奶
 * @Date 2022/5/23 18:40
 * @Version 1.0
 */
@EnableConfigurationProperties(AppThreadPoolProperties.class)
@Configuration
public class AppThreadPoolAutoConfiguration {

    @Autowired
    private AppThreadPoolProperties poolProperties;

    @Primary
    @Bean
    public ThreadPoolExecutor corePool(@Value("${spring.application.name}")String appName){
        return new ThreadPoolExecutor(
                poolProperties.getCorePoolSize(),
                poolProperties.getMaximumPoolSize(),
                poolProperties.getKeepAliveTime(),
                poolProperties.getUnit(),
                new LinkedBlockingQueue<>(poolProperties.getQueueSize()),
                new AppTreadFactory("["+appName+"]-core"),
                poolProperties.getHandler());
    }
}
class AppTreadFactory implements ThreadFactory{
    private String appName;
    private AtomicInteger atomicInteger = new AtomicInteger(0);
    public AppTreadFactory(String appName) {
        this.appName = appName;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        atomicInteger.getAndIncrement();
        thread.setName(appName + atomicInteger.get());
        return thread;
    }
}
